﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using CompilerDLL.SyntaxAnalysis;


namespace CompilerPrinciples.SyntaxAnalysis
{
    public partial class BaseSyntax :LexicalAnalysis.BaseLexical
    {
        #region 构造方法

        public BaseSyntax()
        {
            InitializeComponent();
        }
        #endregion 

        #region 变量

        /// <summary>
        /// 语法分析的返回结果，其中的元素为CompilerDLL.SyntaxAnalysis.BaseSyntaxParseStepStatus
        /// </summary>
        protected ArrayList arraySyntaxAnalysisSteps =
            new ArrayList();

        /// <summary>
        /// 得到的语法树
        /// </summary>
        protected CompilerDLL.SyntaxAnalysis.SyntaxTreeNode syntaxTree;

        /// <summary>
        /// 当前步
        /// </summary>
        protected int intCurrentStep = 0;
        #endregion 

        #region Button按钮事件

        #region 调用词法分析
        /// <summary>
        /// 词法分析
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLexicalAnalysis_Click(object sender, EventArgs e)
        {

            this.tabControl1.SelectTab(0);
            CompilerDLL.LexicalAnalysis.DFA_C_Program dfa_C_Program
                = new CompilerDLL.LexicalAnalysis.DFA_C_Program();
            try
            {
                this.arrayTokens = dfa_C_Program.LexicalMain(this.txtSourceCode.Text);
                this.AddLexem2DataGridView(this.arrayTokens);
            }
            catch (Exception ex)
            {
                MessageBox.Show("错误：" + ex.Message + "请尝试关闭本窗口，并重新执行！", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion 

        #region 初始步
        /// <summary>
        /// 初始步
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnInit_Click(object sender, EventArgs e)
        {
            this.Refresh();
            this.dataGridView1.Rows.Clear();
            this.intCurrentStep = 0;

            this.Add_2DataGridView_Row(arraySyntaxAnalysisSteps, 0);

            //画出语法树
            CompilerDLL.SyntaxAnalysis.BaseSyntaxParseStepStatus stepStatus =
                  (CompilerDLL.SyntaxAnalysis.BaseSyntaxParseStepStatus)arraySyntaxAnalysisSteps[this.intCurrentStep];
            this.syntaxTree =
                 stepStatus.Current_Syntax_Tree;
            this.DrawSyntaxTree(this.syntaxTree, this.panelSyntaxTree.Width / 2, 0, 0, 0);

            this.btnNext.Enabled = true;
            this.btnLast.Enabled = true;
            this.btnFinal.Enabled = true;
        }
        #endregion

        #region 下一步
        /// <summary>
        /// 下一步
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnNext_Click(object sender, EventArgs e)
        {
           
            if (this.intCurrentStep < this.arraySyntaxAnalysisSteps.Count - 1)
            {
                this.Refresh();

                this.intCurrentStep++;
                this.Add_2DataGridView_Row(arraySyntaxAnalysisSteps, this.intCurrentStep);

                //画出语法树
                CompilerDLL.SyntaxAnalysis.BaseSyntaxParseStepStatus stepStatus =
                      (CompilerDLL.SyntaxAnalysis.BaseSyntaxParseStepStatus)arraySyntaxAnalysisSteps[this.intCurrentStep];
                this.syntaxTree =
                     stepStatus.Current_Syntax_Tree;
                this.DrawSyntaxTree(this.syntaxTree, this.panelSyntaxTree.Width / 2, 0, 0, 0);

               
            }
        }
        #endregion

        #region 上一步
        /// <summary>
        /// 上一步
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnLast_Click(object sender, EventArgs e)
        {
            if (this.intCurrentStep > 0)
            {

                this.dataGridView1.Rows.RemoveAt(this.intCurrentStep);
                this.intCurrentStep--;

                //画出语法树
                this.Refresh();
                CompilerDLL.SyntaxAnalysis.BaseSyntaxParseStepStatus stepStatus =
                      (CompilerDLL.SyntaxAnalysis.BaseSyntaxParseStepStatus)arraySyntaxAnalysisSteps[this.intCurrentStep];
                this.syntaxTree =
                     stepStatus.Current_Syntax_Tree;
                this.DrawSyntaxTree(this.syntaxTree, this.panelSyntaxTree.Width / 2, 0, 0, 0);

              
            }
        }
        #endregion

        

        #region 结束步
        /// <summary>
        /// 结束步
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnFinal_Click(object sender, EventArgs e)
        {
            this.Refresh();
            this.Add_2DataGridView(this.arraySyntaxAnalysisSteps);
            this.intCurrentStep = this.arraySyntaxAnalysisSteps.Count - 1;

            //画出语法树
            CompilerDLL.SyntaxAnalysis.BaseSyntaxParseStepStatus stepStatus =
                  (CompilerDLL.SyntaxAnalysis.BaseSyntaxParseStepStatus)arraySyntaxAnalysisSteps[this.intCurrentStep];
            this.syntaxTree =
                 stepStatus.Current_Syntax_Tree;
            this.DrawSyntaxTree(this.syntaxTree, this.panelSyntaxTree.Width / 2, 0, 0, 0);
        }
        #endregion 
        #endregion

        #region 相关辅助函数

        #region  Virtual 向dataGridView1中添加所有行
        /// <summary>
        /// 向dataGridView1中添加所有行
        /// </summary>
        /// <param name="array"></param>
        protected virtual void Add_2DataGridView(ArrayList array)
        {
            //添加到DataGridView
            this.dataGridView1.Rows.Clear();

            for (int i = 0; i < array.Count; i++)
            {

                this.Add_2DataGridView_Row(array, i);
            }
        }
        #endregion

        #region Virtural 向dataGridView1中添加当前行
        protected virtual void Add_2DataGridView_Row(
            ArrayList arraySyntaxAnalysisSteps,
            int currentStep)
         {

         }
        #endregion 

        #region 画出语法树
        /// <summary>
        /// 画出语法树
        /// </summary>
        /// <param name="syntaxTreeNode"></param>
        /// <param name="parentPosition"></param>
        /// <param name="level"></param>
        /// <param name="parentX"></param>
        /// <param name="parentY"></param>
        protected void DrawSyntaxTree(
            CompilerDLL.SyntaxAnalysis.SyntaxTreeNode syntaxTreeNode,
            float parentPosition,
            int level,
            float parentX,
            float parentY)
        {
            //画文法符号
            System.Drawing.Graphics formGraphics = this.panelSyntaxTree.CreateGraphics();

            string drawString = syntaxTreeNode.NodeSymbol;
            System.Drawing.Font drawFont = new System.Drawing.Font("Arial", 10);
            System.Drawing.SolidBrush drawBrush = new System.Drawing.SolidBrush(System.Drawing.Color.Black);
            float x = (float)(parentPosition);
            float y = (float)(syntaxTreeNode.Level * 50 + 50.0);
            System.Drawing.StringFormat drawFormat = new System.Drawing.StringFormat();
            formGraphics.DrawString(drawString, drawFont, drawBrush, x, y, drawFormat);

            //连线
            System.Drawing.Pen myPen = new System.Drawing.Pen(System.Drawing.Color.Red);
            if (syntaxTreeNode.Level > 0)
            {
                formGraphics.DrawLine(myPen, parentX, parentY + 15, x, y);
            }

            myPen.Dispose();
            formGraphics.Dispose();

            if (syntaxTreeNode.ChildNodes != null)
            {
                #region 递归画出子树
                if (syntaxTreeNode.ChildNodes.Count > 0)
                {
                    //实际偏移量
                    int offset = 0;
                    //偏移基数
                    int offSetBase = this.panelSyntaxTree.Width / 2;

                    if (syntaxTreeNode.ChildNodes.Count == 1)
                    {
                        for (int i = 0; i < syntaxTreeNode.ChildNodes.Count; i++)
                        {
                            CompilerDLL.SyntaxAnalysis.SyntaxTreeNode childeNode =
                                (CompilerDLL.SyntaxAnalysis.SyntaxTreeNode)syntaxTreeNode.ChildNodes[i];


                            DrawSyntaxTree(childeNode, parentPosition, childeNode.Level, x, y);
                        }
                    }

                    //如果子节点多于一个ParentPosition先左移一个偏量
                    if (syntaxTreeNode.ChildNodes.Count == 2)
                    {
                        offset = (offSetBase / (level + 1));
                        parentPosition -= offset / 2;

                        for (int i = 0; i < syntaxTreeNode.ChildNodes.Count; i++)
                        {
                            CompilerDLL.SyntaxAnalysis.SyntaxTreeNode childeNode =
                                (CompilerDLL.SyntaxAnalysis.SyntaxTreeNode)syntaxTreeNode.ChildNodes[i];


                            DrawSyntaxTree(childeNode, parentPosition + offset * i, childeNode.Level, x, y);
                        }
                    }

                    if (syntaxTreeNode.ChildNodes.Count == 3)
                    {
                        offset = (offSetBase / (level + 1));
                        parentPosition -= offset / 2;

                        for (int i = 0; i < syntaxTreeNode.ChildNodes.Count; i++)
                        {
                            CompilerDLL.SyntaxAnalysis.SyntaxTreeNode childeNode =
                                (CompilerDLL.SyntaxAnalysis.SyntaxTreeNode)syntaxTreeNode.ChildNodes[i];


                            DrawSyntaxTree(childeNode, parentPosition + (offset / 2) * i, childeNode.Level, x, y);
                        }
                    }
                }
                #endregion
            }
         
        }
        #endregion 

        #region OnPaint绘图
        /// <summary>
        /// 绘图
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            //画出当前语法树
            if((arraySyntaxAnalysisSteps.Count >0)&&(this.intCurrentStep <arraySyntaxAnalysisSteps.Count ))
            {
                   CompilerDLL.SyntaxAnalysis.BaseSyntaxParseStepStatus stepStatus =
                       (CompilerDLL.SyntaxAnalysis.BaseSyntaxParseStepStatus)arraySyntaxAnalysisSteps[this.intCurrentStep];
                   this.syntaxTree =
                        stepStatus.Current_Syntax_Tree;
            }
         
          
                if (this.syntaxTree != null)
            {
                this.DrawSyntaxTree(this.syntaxTree, this.panelSyntaxTree.Width / 2, 0, 0, 0);
            }


        }
        #endregion 
        
        #region 根据每一列的Header的字符串生成列
        /// <summary>
        /// 根据每一列的Header的字符串生成列
        /// </summary>
        /// <param name="arrayColumnHeadString"></param>
        protected void InitDataGridView(ArrayList arrayColumnHeaderString)
        {
            for(int i=0;i<arrayColumnHeaderString.Count;i++)
            {
                DataGridViewColumn dc=new DataGridViewColumn();
                dc.HeaderText=arrayColumnHeaderString[i].ToString();

                // Set the column header style.
                DataGridViewCellStyle columnHeaderStyle =
                    new DataGridViewCellStyle();
                columnHeaderStyle.BackColor = Color.Aqua;
                columnHeaderStyle.Font =
                    new Font("Verdana",8, FontStyle.Regular);
                columnHeaderStyle.Alignment=DataGridViewContentAlignment.TopCenter;
                this.dataGridView1.ColumnHeadersDefaultCellStyle =
                    columnHeaderStyle;


                this.dataGridView1.Columns.Add("DC" + i.ToString(), arrayColumnHeaderString[i].ToString());

            }

        }
        #endregion 

        #region 执行算法分析的主程序
        /// <summary>
        /// 
        /// </summary>
        /// <param name="syntaxParse"></param>
        /// <param name="dlg"></param>
        /// <param name="intPara"></param>
        protected void DoSyntaxParse(
            BaseSyntaxParse syntaxParse,
            DlgGrammar dlg,
            string strPara)
        {
           
            if (this.arrayTokens.Count == 0)
            {
                MessageBox.Show("单词符号串不能为空！请先对源代码输入的文本进行解析。", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            else
            {
                this.tabControl1.SelectTab(1);

                if (syntaxParse.HashForecastTable == null)
                {
                    MessageBox.Show("语法分析所依赖的预测分析表不能为空，请先进行构造！", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                else
                {
                    try
                    {
                       
                        dlg.ShowDialog();

                        ArrayList arrayInputTokens = (ArrayList)this.arrayTokens.Clone();

                        //得到预测分析的计算结果的所有步骤
                        this.arraySyntaxAnalysisSteps = syntaxParse.Syntax_Parse_Main(arrayInputTokens,strPara);

                        //得到语法树
                        this.syntaxTree =
                            new CompilerDLL.SyntaxAnalysis.SyntaxTreeNode();
                        this.syntaxTree = syntaxParse.SyntaxTree;


                        this.Add_2DataGridView(arraySyntaxAnalysisSteps);
                        this.btnInit.Enabled = true;
                        MessageBox.Show("语法分析成功！点击确定进行算法的分步查看。", "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        this.intCurrentStep = this.arraySyntaxAnalysisSteps.Count - 1;
                        this.Refresh();
                        this.DrawSyntaxTree(syntaxTree, this.panelSyntaxTree.Width / 2, 0, 0, 0);
                        this.lblError.Text = "";
                        
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        this.lblError.Text = "语法分析错误！请检查分析结果！";
                        this.Add_2DataGridView(syntaxParse.ArraySyntaxAnalysisSteps );
                        this.syntaxTree = syntaxParse.SyntaxTree;
                        this.Refresh();
                       // this.DrawSyntaxTree(this.syntaxTree, this.panelSyntaxTree.Width / 2, 0, 0, 0);
                    }

                }



            }
        }
        #endregion 

        #endregion
    }
}
